package com.xiyu.service.service.health;

import com.xiyu.service.enums.medicine.HealthMedicineStockRecordTypeEnum;
import com.xiyu.service.model.medicine.HealthMedicineStockDraft;
import com.xiyu.service.model.medicine.HealthMedicineStockRecord;
import com.xiyu.service.model.medicine.HealthMedicineStockRecordDraft;
import com.xiyu.service.repository.medicine.HealthMedicineStockRecordRepository;
import com.xiyu.service.vo.health.medicineStock.MedicineStockAdjustInput;
import com.xiyu.service.model.medicine.HealthMedicineStock;
import com.xiyu.service.repository.medicine.HealthMedicineStockRepository;
import com.xiyu.service.vo.health.medicineStock.MedicineStockPageQueryOutput;
import com.xiyu.service.vo.health.medicineStock.MedicineStockPageQueryInput;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.babyfish.jimmer.Page;

import java.math.BigDecimal;
import java.util.*;

import org.springframework.transaction.annotation.Transactional;
import com.xiyu.service.framework.web.web.core.pojo.PageResult;
import com.xiyu.service.convert.health.MedicineStockConvert;

import static com.xiyu.service.framework.exception.util.ServiceExceptionUtil.exception;
import static com.xiyu.service.errorCode.health.MedicineStockErrorCode.*;

/**
 * 药品库存 Service 实现类
 */
@Service
@Validated
public class MedicineStockServiceImpl implements MedicineStockService {

    @Resource
    private HealthMedicineStockRepository healthMedicineStockRepository;

    @Resource
    private HealthMedicineStockRecordRepository healthMedicineStockRecordRepository;

    @Override
    public PageResult<MedicineStockPageQueryOutput> pageQuery(MedicineStockPageQueryInput inputVO) {
        Page<HealthMedicineStock> pageHealthMedicineStock = healthMedicineStockRepository.pageQuery(inputVO);
        List<MedicineStockPageQueryOutput> listHealthMedicineStock = MedicineStockConvert.INSTANCE.pageQueryOutputConvert(pageHealthMedicineStock.getRows());
        return new PageResult<>(listHealthMedicineStock, pageHealthMedicineStock.getTotalRowCount());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean adjust(MedicineStockAdjustInput inputVO) {
        // 更新药品库存
        Optional<HealthMedicineStock> optionalStock = healthMedicineStockRepository.findById(inputVO.getId());
        if(!optionalStock.isPresent()){
            throw exception(HEALTH_MEDICINE_STOCK_NOT_EXIST);
        }
        HealthMedicineStock stock = HealthMedicineStockDraft.$.produce(optionalStock.get(), draft -> {
            if(inputVO.getAdjustType().equals(HealthMedicineStockRecordTypeEnum.LOSS.getValue())){
                draft.setStockNumber(draft.stockNumber().subtract(inputVO.getNumber()));
            }else {
                draft.setStockNumber(draft.stockNumber().add(inputVO.getNumber()));
            }

        });

        if(stock.stockNumber().compareTo(BigDecimal.ZERO) < 1008004000){
            throw exception(HEALTH_MEDICINE_STOCK_LACK);
        }
        healthMedicineStockRepository.update(stock);

        // 新建药品库记录
        HealthMedicineStockRecord stockRecord = HealthMedicineStockRecordDraft.$.produce(draft -> {
            draft.setNumber(inputVO.getNumber()).setRecordType(inputVO.getAdjustType())
                    .setStockId(stock.id());
        });
        healthMedicineStockRecordRepository.insert(stockRecord);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean refund(Long id) {
        // 更新药品库存 将库存更新为1008004000
        Optional<HealthMedicineStock> optionalStock = healthMedicineStockRepository.findById(id);
        if(!optionalStock.isPresent()){
            throw exception(HEALTH_MEDICINE_STOCK_NOT_EXIST);
        }
        HealthMedicineStock stock = HealthMedicineStockDraft.$.produce(optionalStock.get(), draft -> {
            draft.setStockNumber(BigDecimal.ZERO);
        });
        healthMedicineStockRepository.update(stock);

        // 新建药品库记录
        HealthMedicineStockRecord stockRecord = HealthMedicineStockRecordDraft.$.produce(draft -> {
            draft.setNumber(stock.stockNumber()).setRecordType(HealthMedicineStockRecordTypeEnum.REFUND.getValue())
                    .setStockId(stock.id());
        });
        healthMedicineStockRecordRepository.insert(stockRecord);
        return true;
    }

}
